/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.gzchengguo.cn
* 注意：
* 本软件为www.gzchengguo.cn开发研制，未经购买不得商用
* 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
* 一经发现盗用、分享等行为，将追究法律责任，后果自负
*/
package link.chengguo.orangemall.modules.cart.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import link.chengguo.orangemall.api.OrangeException;
import link.chengguo.orangemall.common.service.impl.BaseServiceImpl;
import link.chengguo.orangemall.common.utils.QueryHelpPlus;
import link.chengguo.orangemall.dozer.service.IGenerator;
import link.chengguo.orangemall.enums.CartTypeEnum;
import link.chengguo.orangemall.enums.OrderInfoEnum;
import link.chengguo.orangemall.enums.ShopCommonEnum;
import link.chengguo.orangemall.modules.activity.domain.OrangeStoreBargain;
import link.chengguo.orangemall.modules.activity.domain.OrangeStoreCombination;
import link.chengguo.orangemall.modules.activity.domain.OrangeStoreSeckill;
import link.chengguo.orangemall.modules.activity.service.OrangeStoreBargainService;
import link.chengguo.orangemall.modules.activity.service.OrangeStoreCombinationService;
import link.chengguo.orangemall.modules.activity.service.OrangeStoreSeckillService;
import link.chengguo.orangemall.modules.activity.service.mapper.OrangeStoreBargainMapper;
import link.chengguo.orangemall.modules.activity.service.mapper.OrangeStoreCombinationMapper;
import link.chengguo.orangemall.modules.activity.service.mapper.OrangeStoreSeckillMapper;
import link.chengguo.orangemall.modules.cart.domain.OrangeStoreCart;
import link.chengguo.orangemall.modules.cart.service.OrangeStoreCartService;
import link.chengguo.orangemall.modules.cart.service.dto.OrangeStoreCartDto;
import link.chengguo.orangemall.modules.cart.service.dto.OrangeStoreCartQueryCriteria;
import link.chengguo.orangemall.modules.cart.service.mapper.StoreCartMapper;
import link.chengguo.orangemall.modules.cart.vo.OrangeStoreCartQueryVo;
import link.chengguo.orangemall.modules.order.domain.OrangeStoreOrder;
import link.chengguo.orangemall.modules.order.service.OrangeStoreOrderService;
import link.chengguo.orangemall.modules.order.service.dto.CountDto;
import link.chengguo.orangemall.modules.product.domain.OrangeStoreProduct;
import link.chengguo.orangemall.modules.product.domain.OrangeStoreProductAttrValue;
import link.chengguo.orangemall.modules.product.service.OrangeStoreProductAttrService;
import link.chengguo.orangemall.modules.product.service.OrangeStoreProductService;
import link.chengguo.orangemall.modules.product.vo.OrangeStoreProductQueryVo;
import link.chengguo.orangemall.modules.user.service.OrangeUserService;
import link.chengguo.orangemall.utils.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
* @author chengguo
* @date 2020-05-12
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class OrangeStoreCartServiceImpl extends BaseServiceImpl<StoreCartMapper, OrangeStoreCart> implements OrangeStoreCartService {

    @Autowired
    private IGenerator generator;

    @Autowired
    private StoreCartMapper orangeStoreCartMapper;
    @Autowired
    private OrangeStoreSeckillMapper storeSeckillMapper;
    @Autowired
    private OrangeStoreBargainMapper orangeStoreBargainMapper;
    @Autowired
    private OrangeStoreCombinationMapper storeCombinationMapper;

    @Autowired
    private OrangeStoreProductService productService;
    @Autowired
    private OrangeStoreProductAttrService productAttrService;
    @Autowired
    private OrangeStoreCombinationService storeCombinationService;
    @Autowired
    private OrangeStoreSeckillService storeSeckillService;
    @Autowired
    private OrangeStoreBargainService storeBargainService;
    @Autowired
    private OrangeStoreOrderService storeOrderService;
    @Autowired
    private OrangeUserService userService;


    /**
     * 删除购物车
     * @param uid uid
     * @param ids 购物车id集合
     */
    @Override
    public void removeUserCart(Long uid, List<String> ids) {
        List<Long> newids = ids.stream().map(Long::new).collect(Collectors.toList());
        orangeStoreCartMapper.delete( Wrappers.<OrangeStoreCart>lambdaQuery()
                .eq(OrangeStoreCart::getUid,uid)
                .in(OrangeStoreCart::getId,newids));
    }

    /**
     * 改购物车数量
     * @param cartId 购物车id
     * @param cartNum 数量
     * @param uid uid
     */
    @Override
    public void changeUserCartNum(Long cartId, int cartNum, Long uid) {
        OrangeStoreCart cart = this.lambdaQuery()
                .eq(OrangeStoreCart::getUid,uid)
                .eq(OrangeStoreCart::getId,cartId)
                .one();
        if(cart == null){
            throw new OrangeException("购物车不存在");
        }

        if(cartNum <= 0){
            throw new OrangeException("库存错误");
        }

        //普通商品库存
        int stock = productService.getProductStock(cart.getProductId()
                ,cart.getProductAttrUnique());
        if(stock < cartNum){
            throw new OrangeException("该产品库存不足"+cartNum);
        }

        if(cartNum == cart.getCartNum()) {
            return;
        }

        OrangeStoreCart storeCart = new OrangeStoreCart();
        storeCart.setCartNum(cartNum);
        storeCart.setId(cartId);

        orangeStoreCartMapper.updateById(storeCart);


    }

    /**
     * 购物车列表
     * @param uid 用户id
     * @param cartIds 购物车id，多个逗号隔开
     * @param status 0-购购物车列表
     * @return map valid-有效购物车 invalid-失效购物车
     */
    @Override
    public Map<String, Object> getUserProductCartList(Long uid, String cartIds, Integer status) {
        QueryWrapper<OrangeStoreCart> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OrangeStoreCart::getUid,uid)
                .eq(OrangeStoreCart::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
                .orderByDesc(OrangeStoreCart::getId);
        if(status == null) {
            wrapper.lambda().eq(OrangeStoreCart::getIsNew, CartTypeEnum.NEW_0.getValue());
        }
        if(StrUtil.isNotEmpty(cartIds)) {
            wrapper.lambda().in(OrangeStoreCart::getId, Arrays.asList(cartIds.split(",")));
        }
        List<OrangeStoreCart> carts = orangeStoreCartMapper.selectList(wrapper);

        List<OrangeStoreCartQueryVo> valid = new ArrayList<>();
        List<OrangeStoreCartQueryVo> invalid = new ArrayList<>();

        for (OrangeStoreCart storeCart : carts) {
            OrangeStoreProductQueryVo storeProduct = null;
            if(storeCart.getCombinationId() != null && storeCart.getCombinationId() > 0){
                storeProduct = ObjectUtil.clone(storeCombinationMapper.combinatiionInfo(storeCart.getCombinationId()));
            }else if(storeCart.getSeckillId() != null && storeCart.getSeckillId() > 0){
                storeProduct = ObjectUtil.clone(storeSeckillMapper.seckillInfo(storeCart.getSeckillId()));
            }else if(storeCart.getBargainId() != null && storeCart.getBargainId() > 0){
                storeProduct = ObjectUtil.clone(orangeStoreBargainMapper.bargainInfo(storeCart.getBargainId()));
            }else{
                //必须得重新克隆创建一个新对象
                storeProduct = ObjectUtil.clone(productService
                        .getStoreProductById(storeCart.getProductId()));
            }

            OrangeStoreCartQueryVo storeCartQueryVo = generator.convert(storeCart, OrangeStoreCartQueryVo.class);

            if(ObjectUtil.isNull(storeProduct)){
                this.removeById(storeCart.getId());
            }else if(ShopCommonEnum.SHOW_0.getValue().equals(storeProduct.getIsShow()) || storeProduct.getStock() == 0){
                storeCartQueryVo.setProductInfo(storeProduct);
                invalid.add(storeCartQueryVo);
            }else{
                if(StrUtil.isNotEmpty(storeCart.getProductAttrUnique())){
                    OrangeStoreProductAttrValue productAttrValue = productAttrService
                            .uniqueByAttrInfo(storeCart.getProductAttrUnique());
                    if(ObjectUtil.isNull(productAttrValue) || productAttrValue.getStock() == 0){
                        storeCartQueryVo.setProductInfo(storeProduct);
                        invalid.add(storeCartQueryVo);
                    }else{
                        storeProduct.setAttrInfo(productAttrValue);
                        storeCartQueryVo.setProductInfo(storeProduct);

                        //设置真实价格
                        //设置VIP价格
                        double vipPrice = userService.setLevelPrice(productAttrValue,uid);
                        if(storeCart.getCombinationId() > 0 || storeCart.getSeckillId() > 0
                                || storeCart.getBargainId() > 0){
                            vipPrice = storeProduct.getPrice().doubleValue();
                        }

                        storeCartQueryVo.setTruePrice(vipPrice);
                        //设置会员价
                        storeCartQueryVo.setVipTruePrice(productAttrValue.getPrice()
                                .doubleValue());
                        storeCartQueryVo.setCostPrice(productAttrValue.getCost()
                                .doubleValue());
                        storeCartQueryVo.setTrueStock(productAttrValue.getStock());

                        valid.add(storeCartQueryVo);

                    }
                }else{
                    //设置VIP价格,营销商品不参与
                    OrangeStoreProductAttrValue productAttrValue = productAttrService
                            .uniqueByAttrInfo(storeCart.getProductAttrUnique());
                    double vipPrice = userService.setLevelPrice(productAttrValue,uid);
                    if(storeCart.getCombinationId() > 0 || storeCart.getSeckillId() > 0
                            || storeCart.getBargainId() > 0){
                        vipPrice = storeProduct.getPrice().doubleValue();
                    }

                    storeCartQueryVo.setTruePrice(vipPrice);
                    // 设置会员价
                    storeCartQueryVo.setVipTruePrice(0d);
                    storeCartQueryVo.setCostPrice(storeProduct.getCost()
                            .doubleValue());
                    storeCartQueryVo.setTrueStock(storeProduct.getStock());
                    storeCartQueryVo.setProductInfo(storeProduct);

                    valid.add(storeCartQueryVo);
                }
            }

        }

        Map<String,Object> map = new LinkedHashMap<>();
        map.put("valid",valid);
        map.put("invalid",invalid);
        return map;
    }

    /**
     * 添加购物车
     * @param uid  用户id
     * @param productId 普通产品编号
     * @param cartNum  购物车数量
     * @param productAttrUnique 属性唯一值
     * @param isNew 1 加入购物车直接购买  0 加入购物车
     * @param combinationId 拼团id
     * @param seckillId  秒杀id
     * @param bargainId  砍价id
     * @return 购物车id
     */
    @Override
    public long addCart(Long uid, Long productId, Integer cartNum, String productAttrUnique,
                       Integer isNew, Long combinationId, Long seckillId, Long bargainId) {

        this.checkProductStock(uid,productId,cartNum,productAttrUnique,combinationId,seckillId,bargainId);
        QueryWrapper<OrangeStoreCart> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OrangeStoreCart::getUid,uid)
                .eq(OrangeStoreCart::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
                .eq(OrangeStoreCart::getProductId,productId)
                .eq(OrangeStoreCart::getIsNew,isNew)
                .eq(OrangeStoreCart::getProductAttrUnique,productAttrUnique)
                .eq(OrangeStoreCart::getBargainId,bargainId)
                .eq(OrangeStoreCart::getCombinationId,combinationId)
                .eq(OrangeStoreCart::getSeckillId,seckillId)
                .orderByDesc(OrangeStoreCart::getId)
                .last("limit 1");

        OrangeStoreCart cart =orangeStoreCartMapper.selectOne(wrapper);

        OrangeStoreCart storeCart = OrangeStoreCart.builder()
                .cartNum(cartNum)
                .productAttrUnique(productAttrUnique)
                .productId(productId)
                .bargainId(bargainId)
                .combinationId(combinationId)
                .seckillId(seckillId)
                .isNew(isNew)
                .uid(uid)
                .build();
        if(cart != null){
            if(CartTypeEnum.NEW_0.getValue().equals(isNew)){
                storeCart.setCartNum(cartNum + cart.getCartNum());
            }
            storeCart.setId(cart.getId());
            orangeStoreCartMapper.updateById(storeCart);
        }else{
            orangeStoreCartMapper.insert(storeCart);
        }

        return storeCart.getId();
    }

    /**
     * 返回当前用户购物车总数量
     * @param uid 用户id
     * @return int
     */
    @Override
    public int getUserCartNum(Long uid) {
        return orangeStoreCartMapper.cartSum(uid);
    }

//    @Override
//    public OrangeStoreCartQueryVo getOrangeStoreCartById(Serializable id){
//        return orangeStoreCartMapper.getOrangeStoreCartById(id);
//    }

    /**
     * 检测商品/秒杀/砍价/拼团库存
     * @param uid  用户ID
     * @param productId  产品ID
     * @param cartNum 购买数量
     * @param productAttrUnique  商品属性Unique
     * @param combinationId  拼团产品ID
     * @param seckillId      秒杀产品ID
     * @param bargainId   砍价产品ID
     */
    @Override
    public void checkProductStock(Long uid, Long productId, Integer cartNum, String productAttrUnique,
                                  Long combinationId, Long seckillId, Long bargainId) {
        Date now = new Date();
        //时间格式问题，date与数据库格式不对应
        //拼团
        if(combinationId != null && combinationId > 0){
            OrangeStoreCombination storeCombination = storeCombinationService
                    .lambdaQuery().eq(OrangeStoreCombination::getId,combinationId)
                    .eq(OrangeStoreCombination::getIsShow, ShopCommonEnum.SHOW_1.getValue())
//                    .le(OrangeStoreCombination::getStartTime,now)
//                    .ge(OrangeStoreCombination::getStopTime,now)
                    .one();

            if(storeCombination == null) {
                throw new OrangeException("该产品已下架或删除");
            }
            if(storeCombination.getStock() < cartNum) {
                throw new OrangeException("该产品库存不足");
            }
            //秒杀
        }else if(seckillId != null && seckillId > 0){
            OrangeStoreSeckill orangeStoreSeckill = storeSeckillService
                    .lambdaQuery().eq(OrangeStoreSeckill::getId,seckillId)
                    .eq(OrangeStoreSeckill::getIsShow, ShopCommonEnum.SHOW_1.getValue())
//                    .le(OrangeStoreSeckill::getStartTime,now)
//                    .ge(OrangeStoreSeckill::getStopTime,now)
                    .one();
            if(orangeStoreSeckill == null){
                throw new OrangeException("该产品已下架或删除");
            }
            if(orangeStoreSeckill.getStock() < cartNum){
                throw new OrangeException("该产品库存不足");
            }
            int  seckillOrderCount = storeOrderService.count(new QueryWrapper<OrangeStoreOrder>()
                    .lambda().eq(OrangeStoreOrder::getUid, uid)
                    .eq(OrangeStoreOrder::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())
                    .eq(OrangeStoreOrder::getSeckillId,seckillId));
            if(orangeStoreSeckill.getNum() <= seckillOrderCount || orangeStoreSeckill.getNum() < cartNum){
                throw new OrangeException("每人限购:"+ orangeStoreSeckill.getNum()+"件");
            }
            //砍价
        }else if(bargainId != null && bargainId > 0){
            OrangeStoreBargain orangeStoreBargain = storeBargainService
                    .lambdaQuery().eq(OrangeStoreBargain::getId,bargainId)
                    .eq(OrangeStoreBargain::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())
//                    .le(OrangeStoreBargain::getStartTime,now)
//                    .ge(OrangeStoreBargain::getStopTime,now)
                    .one();
            if(orangeStoreBargain == null){
                throw new OrangeException("该产品已下架或删除");
            }
            if(orangeStoreBargain.getStock() < cartNum){
                throw new OrangeException("该产品库存不足");
            }

        }else{
            OrangeStoreProduct product = productService
                    .lambdaQuery().eq(OrangeStoreProduct::getId,productId)
                    .eq(OrangeStoreProduct::getIsShow,ShopCommonEnum.SHOW_1.getValue())
                    .one();
            if(product == null){
                throw new OrangeException("该产品已下架或删除");
            }

            int stock = productService.getProductStock(productId,productAttrUnique);
            if(stock < cartNum){
                throw new OrangeException(product.getStoreName()+"库存不足"+cartNum);
            }
        }

    }




    //====================================================================//


    @Override
    //@Cacheable
    public Map<String, Object> queryAll(OrangeStoreCartQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<OrangeStoreCart> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), OrangeStoreCartDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    //@Cacheable
    public List<OrangeStoreCart> queryAll(OrangeStoreCartQueryCriteria criteria){
        return baseMapper.selectList(QueryHelpPlus.getPredicate(OrangeStoreCart.class, criteria));
    }


    @Override
    public void download(List<OrangeStoreCartDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OrangeStoreCartDto orangeStoreCart : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("用户ID", orangeStoreCart.getUid());
            map.put("类型", orangeStoreCart.getType());
            map.put("商品ID", orangeStoreCart.getProductId());
            map.put("商品属性", orangeStoreCart.getProductAttrUnique());
            map.put("商品数量", orangeStoreCart.getCartNum());
            map.put("添加时间", orangeStoreCart.getAddTime());
            map.put("0 = 未购买 1 = 已购买", orangeStoreCart.getIsPay());
            map.put("是否删除", orangeStoreCart.getIsDel());
            map.put("是否为立即购买", orangeStoreCart.getIsNew());
            map.put("拼团id", orangeStoreCart.getCombinationId());
            map.put("秒杀产品ID", orangeStoreCart.getSeckillId());
            map.put("砍价id", orangeStoreCart.getBargainId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<CountDto> findCateName() {
        return orangeStoreCartMapper.findCateName();
    }
}
